<?php
class NewMailService extends AbstractService {
    /**
     * @var NewMailService
     */
    private static $instance;

    /**
     * Get the instance of NewMailService
     * @return NewMailService
     */
    public static function get() {
        if (!self::$instance) {
            self::$instance = new NewMailService();
        }
        return self::$instance;
    }

    /**
     * Construction.
     */
    protected function __construct() {
        parent::__construct();
    }

    /**
     * 处理用户创建时的逻辑
     * @param int $shardId
     * @return void
     */
    public function handleCreate($shardId) {

    }

    /**
     * 处理用户登录时的逻辑
     * @param int $userId
     * @return void
     */
    public function handleLogin($userId) {
        // do nothing
    }

    /**
     * 处理 service 对外提供的全量数据
     * @param int $userId
     * @return array
     */
    public function info($userId) {
        return $this->mailInfo($userId,0,GameService::get()->getReqTime(),true);
    }


    /**
     * @param $userId
     * @param $pageIndex
     * @param $reqTime
     * @param int $param
     * @return array|int
     * @throws SzException
     */
    public function mailInfo($userId,$pageIndex,$reqTime,$param = false) {
        /**
         * @var NewMailVoList $userMailList
         * @var NewMailVo $userMail
         * @var ModuleProfileVo $profile
         */
        $redPoint = 0;
        $mailSettings = SzConfig::get()->loadAppConfig(GameConst::CONFIG_NEW_MAIL, null, true);
        if (!$mailSettings) {
            if ($param) {
                return $redPoint;
            } else {
                return array();
            }
        }

        $profile = SzPersister::get()->getVo($userId, ModuleProfileConst::ORM_NAME_PROFILE);
        if (!$profile) {
            return array();
        }

        $userLevel = $profile->getLevel();
        $userRegisterTime = $profile->getRegisterTime();
        $userMailList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_NEW_MAIL);
        $redisDb = SzDbFactory::get()->getDb($userId, SzAbstractDb::DB_TYPE_REDIS);
        foreach ($mailSettings as $mailSetting) {
            if ($redisDb->get(GameConst::CACHE_KEY_DEL_MAIL.$userId.':'.$mailSetting['mailId'])) {
                continue;
            }
            if ($userRegisterTime > strtotime($mailSetting['registerTime'])) {
                continue;
            }

            list($min,$max) = $mailSetting['level'];
            if ($userLevel < $min || $userLevel > $max) {
                continue;
            }
            if ($reqTime > strtotime($mailSetting['endTime']) || $reqTime < strtotime($mailSetting['startTime'])) {
                continue;
            }
            if ($mailSetting['type'] == 2 && !in_array($userId,$mailSetting['uIds'])) {
                continue;
            }
            $userMail = $userMailList->getElement($mailSetting['mailId'],false);
            if ($userMail) {
                continue;
            }
            $userMail = new NewMailVo($userId,$mailSetting['mailId'], $mailSetting['type'],$mailSetting['title1'],$mailSetting['title2'],$mailSetting['title3'],json_encode($mailSetting['reward'],true),0,$reqTime,true);
            $userMailList->addElement($userMail);
            $userMailList->setElement($mailSetting['mailId'],$userMail);
        }
        SzPersister::get()->setVoList($userMailList);
        $data = $userMailList->toArray();
        if ($data) {
            $count = (int)(count($data) / GameConst::DEFAULT_MAIL_PAGE);
            if ($pageIndex && !$param) {
                $list = array();
                if ($pageIndex > $count) {
                    $pageIndex = $count;
                }
                $min = 1 + ($pageIndex - 1) * GameConst::DEFAULT_MAIL_PAGE;
                $max = GameConst::DEFAULT_MAIL_PAGE * $pageIndex;
                $i = $j = 1;
                foreach ($data as $k=>$v) {
                    if ($j >= $min && $j <= $max) {
                        $mailId[$k] = $v['mailId'];
                        $status[$k]  = $v['status'];
                        $list[] = $v;
                        $i++;
                        if ($i == GameConst::DEFAULT_MAIL_PAGE) {
                            break;
                        }
                    }
                    $j++;
                }
                array_multisort( $status, SORT_ASC, $mailId, SORT_DESC, $list);
                return array(
                    'mail' => $list,
                    'page' => $count
                );
            } else {
                foreach ($data as $k=>$v) {
                    if ($param) {
                        if (!$v['status']) {
                            $redPoint = 1;
                            break;
                        }
                    } else {
                        $mailId[$k] = $v['mailId'];
                        $status[$k]  = $v['status'];
                    }
                }
                if ($param) {
                    return $redPoint;
                }
                array_multisort( $status, SORT_ASC, $mailId, SORT_DESC, $data);
                return array(
                    'mail' => $data,
                    'page' => $count
                );
            }
        } else {
            if ($param) {
                return $redPoint;
            } else {
                return array();
            }
        }
    }

    /**
     * @param $userId
     * @param $mailId
     * @return bool
     * @throws SzException
     */
    public function mailDel($userId,$mailIds) {
        /**
         * @var NewMailVoList $userMailList
         * @var NewMailVo $userMail
         */
        $userMailList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_NEW_MAIL);
        foreach ($mailIds as $mailId) {
            $userMail = $userMailList->getElement($mailId,false);
            if (!$userMail) {
                continue;
            }
            if ($userMail->getStatus()) {
                $userMailList->deleteElement($mailId,false);
                $this->setDelMail($userId,$mailId);
            }
        }
        SzPersister::get()->setVoList($userMailList);
        return true;
    }

    /**
     * @param $userId
     * @param $mailId
     * @return bool
     * @throws SzException
     */
    public function mailReward($userId,$mailIds) {
        /**
         * @var NewMailVoList $userMailList
         * @var NewMailVo $userMail
         */
        $userMailList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_NEW_MAIL);
        foreach ($mailIds as $mailId) {
            $userMail = $userMailList->getElement($mailId,false);
            if ($userMail->getReward() && !$userMail->getStatus()) {
                $outputTid = '';
                foreach ($userMail->getRawReward() as $entityId=>$count) {
                    GameService::get()->handleEntity($userId, $entityId, $count, true);
                    $outputTid .= $entityId.':'.$count.'|';
                }
                // 数据采集:获得
                StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_RESOURCE_OUTPUT, array(
                    'clientData' => array(
                        'tid' => $outputTid,
                        'item' => 'item_buy',
                    )
                ));
                CommonFunctionService::get()->reportResourceUseDetails(GameConst::FUNC_NEW_MAIL,$userId,1,$outputTid,'mailReward');//获得资源上报
            }
            // 数据采集:行为
            StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_USER_ORBIT, array(
                'clientData' => array(
                    'tid' => 'Module:Email|action:claim|',
                    'item' => $mailId,
                    'value' => 1
                )
            ));
            $userMail->setStatus(1);
            $userMailList->updateElement($mailId,$userMail);
        }
        SzPersister::get()->setVoList($userMailList);
        return true;
    }

    /**
     * @param $userId
     * @throws SzException
     */
    public function autoDelMail($userId) {
        /**
         * @var NewMailVoList $userMailList
         * @var NewMailVo $userMail
         */
        $reqTime = GameService::get()->getReqTime();
        $mailDelTime = SzConfig::get()->loadAppConfig(ModuleProfileConst::CONFIG_PROFILE, 'mailDelTime', true);
        if (!$mailDelTime) {
            return;
        }
        $mailDelTime = $mailDelTime['value'];
        $userMailList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_NEW_MAIL);
        foreach ($userMailList->toArray() as $userMail) {
            if (!$userMail['status']) {
                continue;
            }
            if ( ($reqTime - $userMail['createTime']) > $mailDelTime) {
                $userMailList->deleteElement($userMail['mailId'],false);
                $this->setDelMail($userId,$userMail['mailId']);
            }
        }
        SzPersister::get()->setVoList($userMailList);
        return;
    }

    private function setDelMail($userId,$mailId) {
        $redisDb = SzDbFactory::get()->getDb($userId, SzAbstractDb::DB_TYPE_REDIS);
        $mailSettings = SzConfig::get()->loadAppConfig(GameConst::CONFIG_NEW_MAIL, null, true);
        $reqTime = GameService::get()->getReqTime();
        if (isset($mailSettings[$mailId])) {
            $endTime = strtotime($mailSettings[$mailId]['endTime']);
            if ($reqTime < $endTime) {
                $expire = $endTime - $reqTime + 3600;
                $redisDb->set(GameConst::CACHE_KEY_DEL_MAIL.$userId.':'.$mailId,1, $expire);
            }
        }
    }
}